package com.ac.api.base.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.base.context.Context;
import com.base.context.ContextHolder;
import com.base.context.IUser;
import com.base.helper.StringUtils;
import com.ac.api.base.dao.SysMessageMapper;
import com.ac.api.base.entity.MessageType;
import com.ac.api.base.entity.SysMessage;
import com.ac.api.base.service.SysMessageService;
import com.ac.api.base.vo.SysMessageVo;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author mzl
 * @since 2020-11-14
 */
@Service
public class SysMessageServiceImpl extends ServiceImpl<SysMessageMapper, SysMessage> implements SysMessageService {

    @Override
    public List<SysMessageVo> findByExample(SysMessageVo example) {
        joinUserId(example);
        return this.baseMapper.findByExample(buildWrapper(example));
    }

    @Override
    public Page<SysMessageVo> findByPage(Page page, SysMessageVo example) {
        joinUserId(example);
        /** 不进行 count sql 优化，解决 MP 无法自动优化 SQL 问题 */
        page.setOptimizeCountSql(false);
        return page.setRecords(baseMapper.findByExample(buildWrapper(example), page));
    }

    @Override
    public SysMessageVo findById(Integer id) {
        SysMessageVo sysMessage = this.baseMapper.findById(id);
        if (null != sysMessage && "0".equals(sysMessage.getReadstate())) {
            this.read(Arrays.asList(sysMessage));
        }
        return sysMessage;
    }

    @Override
    public List<SysMessage> findByIds(List<Integer> ids) {
        if (null != ids && ids.size() > 0) {
            QueryWrapper<SysMessage> wrapper = new QueryWrapper<>();
            wrapper.lambda().in(SysMessage::getId, ids)
                    .eq(SysMessage::getState, "1");
            return super.list(wrapper);
        }
        return Collections.emptyList();
    }

    @Override
    public void read(List<SysMessage> sysMessages) {
        if (null != sysMessages && sysMessages.size() > 0) {
            for (SysMessage sysMessage : sysMessages) {
                if ("0".equals(sysMessage.getReadstate())) {
                    sysMessage.setReadstate("1");
                    sysMessage.setReadtime(new Date());
                }
            }
            super.updateBatchById(sysMessages);
        }
    }

    @Override
    public void batchRead(List<Integer> ids) {
        List<SysMessage> sysMessages = this.findByIds(ids);
        this.read(sysMessages);
    }

    @Override
    public Integer noReadCount(Integer userid) {
        return this.baseMapper.userUnReadCount(userid);
    }


    @Override
    public void sendMessage(Integer senduserid, Integer targetid, MessageType messageType, String title,
                            String message, String link) {
        SysMessage sysMessage = new SysMessage();
        sysMessage.setSendUserId(senduserid);
        sysMessage.setUserid(targetid);
        sysMessage.setType(messageType);
        sysMessage.setTitle(title);
        sysMessage.setMessage(message);
        sysMessage.setLink(link);
        sysMessage.setCreatetime(new Date());
        sysMessage.setReadstate("0");
        sysMessage.setState("1");
        super.save(sysMessage);
    }

    @Override
    public void sendMessage(Integer senduserid, List<Integer> targetids, MessageType messageType, String title,
                            String message, String link) {
        if (null != targetids && targetids.size() > 0) {
            List<SysMessage> sysMessages = new ArrayList<>();
            SysMessage       sysMessage  = null;
            for (Integer targetid : targetids) {
                sysMessage = new SysMessage();
                sysMessage.setSendUserId(senduserid);
                sysMessage.setUserid(targetid);
                sysMessage.setType(messageType);
                sysMessage.setTitle(title);
                sysMessage.setMessage(message);
                sysMessage.setLink(link);
                sysMessage.setCreatetime(new Date());
                sysMessage.setReadstate("0");
                sysMessage.setState("1");
                sysMessages.add(sysMessage);
            }
            super.saveBatch(sysMessages);
        }
    }

    @Override
    public Boolean deleteByUserId(List<Integer> userIds) {
        QueryWrapper<SysMessage> wrapper = new QueryWrapper<>();
        wrapper.lambda().in(SysMessage::getUserid, userIds);
        return super.remove(wrapper);
    }

    /**
     * 构建查询
     *
     * @param example
     * @return
     */
    private QueryWrapper<SysMessageVo> buildWrapper(SysMessageVo example) {
        QueryWrapper<SysMessageVo> wrapper      = new QueryWrapper<>();
        Integer                    userid       = example.getUserid();
        String                     userName     = example.getUserName();
        Integer                    sendUserId   = example.getSendUserId();
        String                     sendUserName = example.getSendUserName();
        String                     readstate    = example.getReadstate();
        String                     title     = example.getTitle();

        wrapper.lambda()
                .like(StringUtils.isNotEmpty(title), SysMessageVo::getTitle, title)
                .eq(null != userid, SysMessageVo::getUserid, userid)
                .eq(null != sendUserId, SysMessageVo::getSendUserId, sendUserId)
                .eq(null != readstate, SysMessageVo::getReadstate, readstate)
                .eq(SysMessageVo::getState, "t")
                .orderByDesc(SysMessageVo::getId);

        wrapper.like(StringUtils.isNotEmpty(userName), "user_name", userName)
                .like(StringUtils.isNotEmpty(sendUserName), "send_user_name", sendUserName);

        return wrapper;
    }

    /**
     * 添加查询条件当前登录订单id必填
     *
     * @param example
     */
    private void joinUserId(SysMessageVo example) {
        Context context     = ContextHolder.currentContext();
        IUser   currentUser = context.currentUser();
        example.setUserid(currentUser.getId());
    }

}
